﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion

#region Usings

using System;
using ScrumTable.BL.DM.DataManagement;
using ScrumTable.Common;

#endregion

namespace ScrumTable.UI.ViewModel
{
    /// <summary>
    /// User story for the View model
    /// </summary>
    public class TaskViewModel : ViewModelItemBase<Task>
    {

        #region Declarations
        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------
        /// <summary>
        /// The Task from the BL.
        /// </summary>
   
        private bool _timeUpdateBatch = false;
        private bool _timeLocked = false;
 
        #endregion

        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------
        
    
       

        /// <summary>
        /// Func for changing the state
        /// </summary>
        public static readonly Func<object, ScrumState, CanDropResult> CanChangeState = CanChangeStateResult<TaskViewModel>;
 
        /// <summary>
        /// Gets the id of the task.
        /// </summary>
        public UserStoryViewModel ParentAsStoryViewModel 
        {
            get { return new UserStoryViewModel((UserStory)Original.Parent); }
        }

      

        /// <summary>
        /// Specifies the tasks estimate.
        /// </summary>
        public double? Estimate
        {
            get
            {
                return Original.Estimate;
            }
            set
            {
                Original.Estimate = value;
                
                SendPropertyChanged("Estimate");
                SendPropertyChanged("WorkTimeForSlider");
              
                Save();

                if (Original.RemainingWork == null || (RemainingWork.Equals(0) && CompletedWork.Equals(0)))
                    RemainingWork = value;

                SendIsEstimatedTimeLockedChanged();
            }
        }

        /// <summary>
        /// Sorting property
        /// </summary>
        public override  double? Sorting
        {
            get { return Priority; }
        }


        /// <summary>
        /// Specifies the tasks remaining work.
        /// </summary>
        public double? RemainingWork
        {
            get
            {
                return IsDisposed ? null : Original.RemainingWork;
            }
            set
            {
                Original.RemainingWork = value;
                SendPropertyChanged("RemainingWork");
                SendPropertyChanged("WorkTimeForSlider");
                SendIsEstimatedTimeLockedChanged();
                Save();
            }
        }

        /// <summary>
        /// Specifies the tasks completed work.
        /// </summary>
        public double? CompletedWork
        {
            get
            {
                return IsDisposed ? null : Original.CompletedWork;
            }
            set
            {


                Original.CompletedWork = value;

                SendPropertyChanged("CompletedWork");
                SendPropertyChanged("WorkTimeForSlider");
                SendIsEstimatedTimeLockedChanged();
                Save();
            }
        }
      

        /// <summary>
        /// Specifies priority of the task.
        /// </summary>
        public int Priority
        {
            get { return IsDisposed ? 0 : Original.Priority; }
            set
            {
                Original.Priority = value;
                SendPropertyChanged("Priority");
                Save();
            }
        }

       
        /// <summary>
        /// Checks if Estimate == RemainingWork + CompletedWork;
        /// Set this value result will result in loosing the "RemainingWork Time". 
        /// </summary>
        public bool IsEstimatedTimeLocked
        {

            set
            {   
                _timeLocked = value;
                if (_timeLocked && Estimate >= CompletedWork)
                {                 
                    RemainingWork = Estimate - CompletedWork;
                }
                SendPropertyChanged("IsEstimatedTimeLocked");
            }
            get
            {
                return _timeLocked;
            }
        }


        /// <summary>
        /// Get: CompletedWork
        /// Set:  RemainingWork = Estimate - value 
        /// CompletedWork = value
        /// </summary>
        public double WorkTimeForSlider 
        {
            get
            {
                return CompletedWork.GetValueOrDefault(0);
            }
            set
            {
                _timeUpdateBatch = true;
                RemainingWork = Estimate - value;
                CompletedWork = value;
                _timeUpdateBatch = false;
                SendPropertyChanged("IsEstimatedTimeLocked");
                
            }
        }

        private void SendIsEstimatedTimeLockedChanged()
        {
            if (!_timeUpdateBatch && _timeLocked)
            {
                _timeLocked = Estimate == RemainingWork + CompletedWork;
                SendPropertyChanged("IsEstimatedTimeLocked");
            }
        }

        #endregion

        #region Constructors / Destructor
        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------
        /// <summary>
        /// Initializes a new instance of the <see cref="TaskViewModel"/> class.
        /// </summary>
        /// <param name="task">The task.</param>
        public TaskViewModel(Task task):base(task)
        {
            
            _timeLocked = Estimate == RemainingWork + CompletedWork;
        }
      
        #endregion

        #region Overrides
        //--------------------------------------------------------------------
        // Overrides
        //--------------------------------------------------------------------
 
        /// <summary>
        /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
        /// </summary>
        /// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
        /// <returns>
        /// 	<c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
        /// </returns>
        /// <exception cref="T:System.NullReferenceException">
        /// The <paramref name="obj"/> parameter is null.
        /// </exception>
        public override bool Equals(object obj)
        {
            if (!(obj is TaskViewModel)) return false;
            return Equals(obj as TaskViewModel);
        }

        /// <summary>
        /// Equalses the specified other.
        /// </summary>
        /// <param name="other">The other.</param>
        /// <returns></returns>
        public bool Equals(TaskViewModel other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return other.Original == Original;
        }

        /// <summary>
        /// Returns a hash code for this instance.
        /// </summary>
        /// <returns>
        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
        /// </returns>
        public override int GetHashCode()
        {
            return (Original != null ? Original.GetHashCode() : 0);
        }

        #endregion

        #region Methods
        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------
 

        #endregion

        #region Events
        //--------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------


        

        #endregion
    }

   
}